package com.dycong.common.api_design.sign.encrypt;

import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * MD5加密工具类
 *
 * @author chenanzhi 2015年8月28日 下午1:21:46
 * @since 1.0
 */
public class MD5Encrypt {

    private static final String ALGORITHM = "MD5";

    private static final String HANDLE = "my_tools_md5_encrypt"; // 句柄

    private static final String DEFAULT_CHARSET = "UTF-8";

    // 全局数组
    private final static String[] STR_DIGITS = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
            "e", "f"};

    // 返回形式为数字跟字符串
    private static String byteToArrayString(byte bByte) {
        int iRet = bByte;
        if (iRet < 0) {
            iRet += 256;
        }
        int iD1 = iRet / 16;
        int iD2 = iRet % 16;
        return STR_DIGITS[iD1] + STR_DIGITS[iD2];
    }

    // 转换字节数组为16进制字串
    private static String byteToString(byte[] bByte) {
        StringBuilder sBuffer = new StringBuilder();
        for (byte aBByte : bByte) {
            sBuffer.append(byteToArrayString(aBByte));
        }
        return sBuffer.toString();
    }

    /**
     * @param strObj
     * @return
     */
    public static String getmd5code(String strObj) {
        return getmd5code(strObj, DEFAULT_CHARSET);
    }

    /**
     * TODO(MD5加密,有句柄)
     *
     * @param strObj
     * @param charset
     * @return
     */
    public static String getmd5code(String strObj, String charset) {
        strObj = strObj + HANDLE;
        String resultString = null;
        try {
            resultString = sign(strObj, charset);
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
            ex.printStackTrace();
        }
        return resultString;
    }

    public static String getmd5codeprototype(String strObj) {
        return getmd5codeprototype(strObj, DEFAULT_CHARSET);
    }

    /**
     * TODO(MD5加密,没有句柄)
     *
     * @param strObj
     * @param charset
     * @return
     */
    public static String getmd5codeprototype(String strObj, String charset) {
        String resultString = null;
        try {
            resultString = sign(strObj, charset);
        } catch (NoSuchAlgorithmException | UnsupportedEncodingException ex) {
            ex.printStackTrace();
        }
        return resultString;
    }

    private static String sign(String str, String charset) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest md = MessageDigest.getInstance(ALGORITHM);
        return (StringUtils.isEmpty(charset) || StringUtils.isBlank(charset)) ?
                byteToString(md.digest(str.getBytes(DEFAULT_CHARSET)))
                : byteToString(md.digest(str.getBytes(charset)));
    }

    public static boolean verify(String text, String sign, String charset) {
        return StringUtils.equals(sign, getmd5code(text + HANDLE, charset));
    }

    public static boolean verify(String text, String sign) {
        return StringUtils.equals(sign, getmd5code(text + HANDLE, DEFAULT_CHARSET));
    }

    public static boolean verifyPrototype(String text, String sign) {
        return StringUtils.equals(sign, getmd5codeprototype(text, DEFAULT_CHARSET));
    }

    public static boolean verifyPrototype(String text, String sign, String charset) {
        return StringUtils.equals(sign, getmd5codeprototype(text, charset));
    }

}
